/*--------------------------------------------------------------------------------------+
|
|     $Source: samples/SampleDgnDbEditor/MoveShipping%Class%Tool.cpp $
|
|  $Copyright: (c) 2014 Bentley Systems, Incorporated. All rights reserved. $
|
+--------------------------------------------------------------------------------------*/
#include "MoveShipping%Class%Tool.h"

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
bool MoveShipping%Class%Tool::IsMoveValid (ECClassId ecClassId)
    {
    return Shipping%Class%ItemHandler::Get().CanHandleClass (m_writeModel.GetDgnProject(), ecClassId);
    }

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
void MoveShipping%Class%Tool::_OnDynamicFrame (DgnButtonEventCP ev)
    {
    if (!m_itemPtr.IsValid())
        return;

    Transform localToWorld;
    if (BSISUCCESS != Shipping%Class%ItemHandler::Get().GetPlacement (localToWorld, *m_itemPtr))
        return;

    // show move in dynamics by replacing placement origin with current cursor location
    localToWorld.SetTranslation (*ev->GetPoint());
    Shipping%Class%ItemHandler::Get().SetPlacement (*m_itemPtr, localToWorld);

    // create the graphics that will be shown for this dynamic frame
    PhysicalGraphicsPtr graphicsPtr = DgnGraphicsUtils::GetItemPhysicalGraphics (Shipping%Class%ItemHandler::Get(), m_writeModel, *m_itemPtr);
    if (!graphicsPtr.IsValid())
        return;

    // tell the tool framework to redraw the newly created graphics
    RedrawElems redrawElems;
    redrawElems.SetDrawMode (DgnDrawMode::TempDraw);
    redrawElems.SetDrawPurpose (DrawPurpose::Dynamics);
    redrawElems.SetDynamicsViews (IViewManager::GetActiveViewSet(), ev->GetViewport());
    redrawElems.DoRedraw (graphicsPtr->GetElementHandleR());
    }

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
bool MoveShipping%Class%Tool::_OnDataButton (DgnButtonEventCP ev)
    {
    if (IsMoveInProgress())
        {
        // get current placement
        Transform localToWorld;
        if (BSISUCCESS != Shipping%Class%ItemHandler::Get().GetPlacement (localToWorld, *m_itemPtr))
            return false;

        // update placement based on current datapoint
        localToWorld.SetTranslation (*ev->GetPoint());
        Shipping%Class%ItemHandler::Get().UpdatePlacement (m_writeModel.GetDgnProject(), m_moveItemKey, localToWorld);

        // regenerate/update physical graphics for item
        if (BSISUCCESS != DgnGraphicsUtils::UpdateItemPhysicalGraphics (Shipping%Class%ItemHandler::Get(), m_writeModel, m_moveItemKey, m_moveElementId))
            return false;

        // commit the transaction
        _CloseCurrentTxn();

        // put the newly moved element into the selection set
        SelectionSetManager::GetManager().ReplaceWithElement (m_writeModel.FindElementById (m_moveElementId), true);

        _OnRestartTool();
        return false;
        }

    // a move is not currently in progress so try to identify an element to move
    HitPathCP hitPathCP = ElementLocateManager::GetManager().DoLocateHitPath (NULL, NULL, true, ev->GetPoint(), ev->GetViewport(), 0);
    if (hitPathCP && hitPathCP->GetHeadElem())
        {
        EditElementHandle eeh (hitPathCP->GetHeadElem());
        ECInstanceKey itemKey;

        if (DgnECPersistence::GetPrimaryInstanceOnElement (itemKey, eeh) && IsMoveValid (itemKey.GetECClassId()))
            {
            m_itemPtr = Shipping%Class%ItemHandler::Get().ReadItemInstance (m_writeModel.GetDgnProject(), itemKey);
            if (m_itemPtr.IsValid())
                {
                m_moveElementId = hitPathCP->GetHeadElem()->GetElementId();
                m_moveItemKey = itemKey;

                _BeginDynamics();
                return false;
                }
            }
        }

    // no elements to move were found, reset state for next _OnDataButton
    m_moveElementId.Invalidate();
    m_moveItemKey = ECInstanceKey();
    _ClearSelection();
    return false;
    }

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
bool MoveShipping%Class%Tool::_OnResetButton (DgnButtonEventCP ev)
    {
    _OnRestartTool();
    return false;
    }

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
void MoveShipping%Class%Tool::_OnRestartTool() 
    {
    if (GetDynamicsStarted())
        _EndDynamics();

    if (_CheckSingleShot())
        return;

    MoveShipping%Class%Tool* newTool = new MoveShipping%Class%Tool (m_writeModel);
    newTool->InstallTool();
    }

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
void MoveShipping%Class%Tool::_OnPostInstall()
    {
    T_Super::_OnPostInstall();

    AccuDraw::GetInstance().Deactivate();
    AccuSnap::GetInstance().EnableLocate (true);
    AccuSnap::GetInstance().EnableSnap (false);
    }

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
MoveShipping%Class%Tool::MoveShipping%Class%Tool (DgnModelR writeModel) 
    : DgnPrimitiveTool (0), m_writeModel (writeModel)
    {
    }
